﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using OpenPose.MyInterface;
using System.Linq;
using Score;
//这里因为FFT属于积分变换领域，所以使用IntegralTransforms。


/// <summary>
/// 每次进入舞蹈时动态创建一个实例
/// </summary>
public class ScoreCal : MonoBehaviour
{

    // res = sum(abs(a-b))
    public static float list_distance(float[] a, float[] b)
    {
        float res = 0.0f;
        for (int i = 0; i < a.Length; i++)
        {
            res += Math.Abs(a[i] - b[i]);
        }
        return res;
    }

    // 舞蹈开始时间
    //private DateTime starttime;
    // npc
    private DancingNPC npc;

    // 已经计算的动作数量
    private int finish;
    // npc动作分割点与本次舞蹈对应的系统时间
    //private DateTime[] coresp_time;
    private static double Maxdistance =  12000;
    private static double Mindistance = 0;
    private static double Maxangledistance = 25;
    private static double Minangledistance = 0;
    private static double Maxangledistance2 = 26;
    private static double Minangledistance2 = 20.5;
    // OpenPose
    private OpenPoseOutput openPose;

    // 用户得分
    public List<float> scores;

    // 开始舞蹈时 动态创建一个ScroeCal
    void Start()
    {
        openPose = GameObject.Find("OpenPose").GetComponent<OpenPoseOutput>();
        npc = transform.parent.GetComponent<ScoreOutput>().npc;
        finish = 0;
        scores = new List<float>();
    }

    // Update is called once per frame
    void Update()
    {
        //用协程代替
        StartCoroutine(calculating());

    }
    //计算两段序列之间各个点之间的距离，欧氏距离
    private static double EuclideanDistance(double[] point1, double[] point2)
    {
        double distSqr = 0;
        for (int i = 0; i < 2; i++)
        {
            distSqr += Math.Pow(point1[i] - point2[i], 2);
        }
        return Math.Sqrt(distSqr);
    }

    //计算两端序列之间各个点之间的角度，曼哈顿距离
    private static double ManHattanDistance(double point1, double point2)
    {
        double distSqr = 0;
        distSqr = Math.Abs(point1 - point2);
        return distSqr;
    }

    /// <summary>
    /// 将得到的位置点进行格式转换
    /// </summary>
    /// <param name="point"></param>
    /// <returns></returns>
    private static ArrayList TurntoArr(float[] pointx, float[] pointy)
    {
        ArrayList get = new ArrayList();
        for (int i = 0; i < pointx.Length; i = i + 1)
        {
            double[] Turntoar = { 0, 1 };

            Turntoar[0] = Convert.ToDouble(pointx[i]);
            Turntoar[1] = Convert.ToDouble(pointy[i]);
            get.Add(Turntoar);
        }
        return get;
    }
    /// <summary>
    /// 得到的角度点进行格式转换
    /// </summary>
    /// <param name="angle"></param>
    /// <returns></returns>
    private static ArrayList TurntoArr_angle(float[] angle)
    {
        ArrayList get = new ArrayList();
        for (int i = 0; i < angle.Length; i = i + 1)
        {
            double angles = 0;
            angles = angle[i];
            get.Add(angles);
        }
        return get;

    }
    public static float[] Filter(float[] inData, float[] filterArr)
    {
        float[] outArr = new float[25];
        outArr = inData;

        return outArr;
    }

    /// <summary>
    /// 骨骼角度dtw算法
    /// </summary>
    /// <param name="user"></param>
    /// <param name="npc"></param>
    /// <returns></returns>
    public static double dtw_angle(ArrayList user, ArrayList npc)
    {
        ArrayList user2 = new ArrayList(user);
        ArrayList npc2 = new ArrayList(npc);
        int r = user2.Count;
        int c = npc2.Count;
        double[,] cell = new double[r + 1, c + 1];
        double[,] cell1 = new double[r, c];

        for (int i = 0; i < r + 1; i++)
        {
            for (int j = 0; j < c + 1; j++)
            {
                cell[i, j] = 0;

                cell[0, j] = double.PositiveInfinity;

            }
            cell[i, 0] = double.PositiveInfinity;
        }
        cell[0, 0] = 0;
        for (int i = 0; i < r; i++)
        {
            for (int j = 0; j < c; j++)
            {
                cell1[i, j] = 0;

            }

        }
        for (int i = 0; i < r; i++)
        {
            for (int j = 0; j < c; j++)
            {
                cell1[i, j] = ManHattanDistance((double)(user2[i]), (double)(npc2[j]));

                cell[i + 1, j + 1] = cell1[i, j];
            }
        }
        //动态时间规划
        for (int i = 0; i < r; i++)
        {
            for (int j = 0; j < c; j++)
            {
                List<double> minlist = new List<double>();
                minlist.Add(cell[i, j]);
                for (int k = 1; k < 2; k++)
                {
                    int i_k = (i + k) < r ? (i + k) : r;
                    int j_k = (j + k) < c ? (j + k) : c;

                    minlist.Add(cell[i_k, j] * 1.0);
                    minlist.Add(cell[i, j_k] * 1.0);

                }

                cell1[i, j] += minlist.Min();
                cell[i + 1, j + 1] += minlist.Min();
            }
        }
        return cell1[r - 1, c - 1];
    }

    /// <summary>
    /// dtw核心算法
    /// </summary>
    /// <param name="user"></param>
    /// <param name="npc"></param>
    /// <returns></returns>
    public static double dtw(ArrayList user, ArrayList npc)
    {
        ArrayList user2 = new ArrayList(user);
        ArrayList npc2 = new ArrayList(npc);
        int r = user2.Count;
        int c = npc2.Count;
        double[,] cell = new double[r + 1, c + 1];
        double[,] cell1 = new double[r, c];

        for (int i = 0; i < r + 1; i++)
        {
            for (int j = 0; j < c + 1; j++)
            {
                cell[i, j] = 0;

                cell[0, j] = double.PositiveInfinity;

            }
            cell[i, 0] = double.PositiveInfinity;
        }
        cell[0, 0] = 0;
        for (int i = 0; i < r; i++)
        {
            for (int j = 0; j < c; j++)
            {
                cell1[i, j] = 0;

            }

        }
        for (int i = 0; i < r; i++)
        {
            for (int j = 0; j < c; j++)
            {
                cell1[i, j] = EuclideanDistance((double[])(user2[i]), (double[])(npc2[j]));
                cell[i + 1, j + 1] = cell1[i, j];
            }
        }
        //动态时间规划
        for (int i = 0; i < r; i++)
        {
            for (int j = 0; j < c; j++)
            {
                List<double> minlist = new List<double>();
                minlist.Add(cell[i, j]);
                for (int k = 1; k < 2; k++)
                {
                    int i_k = (i + k) < r ? (i + k) : r;
                    int j_k = (j + k) < c ? (j + k) : c;

                    minlist.Add(cell[i_k, j] * 1.0);
                    minlist.Add(cell[i, j_k] * 1.0);

                }

                cell1[i, j] += minlist.Min();
                cell[i + 1, j + 1] += minlist.Min();
            }
        }
        return cell1[r - 1, c - 1];
    }

    /// <summary>
    /// 根据时间戳来进行插值操作
    /// </summary>
    /// <param name="timeA"></param>
    /// <param name="timeB"></param>
    /// <returns></returns>
    public static string GetTime(DateTime timeA, DateTime timeB)
    {
        TimeSpan ts = timeB - timeA;    //计算时间差
        string time = ts.TotalSeconds.ToString();   //将时间差转换为秒
        return time;
    }
    public static double score_angle2(List<PoseKeyPoints> npc_pose_seg, List<PoseKeyPoints> user_pose_seg)
    {
        float[] filterArr = new float[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
        int count = 0;
        double distance = 0;
        if (npc_pose_seg.Count > user_pose_seg.Count)
        {
            int index = 1;
            float[] angle = new float[npc_pose_seg[0].numKey];
            foreach (var item in user_pose_seg)
            {
                for (int i = index; i < npc_pose_seg.Count; i++)
                {
                    if (npc_pose_seg[i].coresp_time >= item.coresp_time)
                    {

                        double getfirst = Convert.ToDouble(GetTime(npc_pose_seg[i - 1].coresp_time, item.coresp_time));
                        double getsecond = Convert.ToDouble(GetTime(item.coresp_time, npc_pose_seg[i].coresp_time));

                        if (getfirst < 0)
                        {
                            getfirst = 0;
                        }
                        if (getsecond == 0)
                        {
                            for (int j = 0; j < npc_pose_seg[i].numKey; j++)
                            {
                                angle[j] = npc_pose_seg[i].angle[j];

                            }

                            ArrayList usergetequal = TurntoArr_angle(Filter(item.angle,filterArr));
                            ArrayList npcgetequal = TurntoArr_angle(Filter(angle,filterArr));

                            distance += dtw_angle(usergetequal, npcgetequal);
                            count = count + 1;
                            index = i;
                            break;
                        }

                        for (int j = 0; j < npc_pose_seg[i].numKey; j++)
                        {
                            angle[j] = Convert.ToSingle((getfirst / (getfirst + getsecond)) * (npc_pose_seg[i - 1].angle[j])) + Convert.ToSingle((getsecond / (getfirst + getsecond)) * (npc_pose_seg[i].angle[j]));


                        }
                        ArrayList userget = TurntoArr_angle(Filter(item.angle,filterArr));
                        ArrayList npcget = TurntoArr_angle(Filter(angle,filterArr));
                        distance += dtw_angle(userget, npcget);
                        count = count + 1;
                        index = i;
                        break;
                    }
                }
            }

        }
        else if (npc_pose_seg.Count == user_pose_seg.Count)
        {
            for (int i = 0; i < npc_pose_seg.Count; i++)
            {
                ArrayList userget = TurntoArr_angle(Filter(user_pose_seg[i].angle,filterArr));
                ArrayList npcget = TurntoArr_angle(Filter(npc_pose_seg[i].angle,filterArr));
                distance += dtw_angle(userget, npcget);
                count = count + 1;
            }
        }
        else
        {
            int index = 1;
            float[] angle = new float[npc_pose_seg[0].numKey];

            foreach (var item in npc_pose_seg)
            {
                for (int i = index; i < user_pose_seg.Count; i++)
                {
                    if (user_pose_seg[i].coresp_time >= item.coresp_time)
                    {

                        double getfirst = Convert.ToDouble(GetTime(user_pose_seg[i - 1].coresp_time, item.coresp_time));
                        double getsecond = Convert.ToDouble(GetTime(item.coresp_time, user_pose_seg[i].coresp_time));

                        if (getfirst < 0)
                        {
                            getfirst = 0;
                        }
                        if (getsecond == 0)
                        {
                            for (int j = 0; j < user_pose_seg[i].numKey; j++)
                            {
                                angle[j] = user_pose_seg[i].angle[j];

                            }
                            ArrayList usergetequal = TurntoArr_angle(Filter(item.angle,filterArr));
                            ArrayList npcgetequal = TurntoArr_angle(angle);
                            distance += dtw(usergetequal, npcgetequal);
                            count = count + 1;
                            index = i;
                            break;
                        }

                        for (int j = 0; j < user_pose_seg[i].numKey; j++)
                        {
                            angle[j] = Convert.ToSingle((getfirst / (getfirst + getsecond)) * (user_pose_seg[i - 1].angle[j])) + Convert.ToSingle((getsecond / (getfirst + getsecond)) * (user_pose_seg[i].angle[j]));


                        }
                        ArrayList userget = TurntoArr_angle(Filter(item.angle,filterArr));
                        ArrayList npcget = TurntoArr_angle(Filter(angle,filterArr));
                        distance += dtw_angle(userget, npcget);
                        count = count + 1;
                        index = i;
                        break;
                    }
                }
            }
        }
        double distancescore = 0;
       
        distance = distance / count;
        return distance; 
        if (distance > Maxangledistance2)
            return 0;
        else if (distance < Minangledistance2)
            return 1;
        else
        {

            distancescore = (1 - (distance - Minangledistance2) / (Maxangledistance2 - Minangledistance2));

        }
        return distancescore;

    }
    public static double score_angle(List<PoseKeyPoints> npc_pose_seg, List<PoseKeyPoints> user_pose_seg)
    {
        int count = 0;
        double distance = 0;
        double distancemax = 0;
        float[] maxzero = new float[] { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
        if (npc_pose_seg.Count > user_pose_seg.Count)
        {
            int index = 1;
            float[] angle = new float[npc_pose_seg[0].numKey];
            foreach (var item in user_pose_seg)
            {
                for (int i = index; i < npc_pose_seg.Count; i++)
                {
                    if (npc_pose_seg[i].coresp_time >= item.coresp_time)
                    {

                        double getfirst = Convert.ToDouble(GetTime(npc_pose_seg[i - 1].coresp_time, item.coresp_time));
                        double getsecond = Convert.ToDouble(GetTime(item.coresp_time, npc_pose_seg[i].coresp_time));

                        if (getfirst < 0)
                        {
                            getfirst = 0;
                        }
                        if (getsecond == 0)
                        {
                            for (int j = 0; j < npc_pose_seg[i].numKey; j++)
                            {
                                angle[j] = npc_pose_seg[i].angle[j];

                            }
                            ArrayList usergetequal = TurntoArr_angle(item.angle);
                            ArrayList npcgetequal = TurntoArr_angle(angle);
                            ArrayList maxqual = TurntoArr_angle(maxzero);
                            distance += dtw_angle(usergetequal, npcgetequal);
                            
                            distancemax += dtw_angle(npcgetequal, maxqual);
                            count = count + 1;
                            index = i;
                            break;
                        }

                        for (int j = 0; j < npc_pose_seg[i].numKey; j++)
                        {
                            angle[j] = Convert.ToSingle((getfirst / (getfirst + getsecond)) * (npc_pose_seg[i - 1].angle[j])) + Convert.ToSingle((getsecond / (getfirst + getsecond)) * (npc_pose_seg[i].angle[j]));


                        }
                        ArrayList userget = TurntoArr_angle(item.angle);
                        ArrayList npcget = TurntoArr_angle(angle);
                        ArrayList maxqual2 = TurntoArr_angle(maxzero);
                        distance += dtw_angle(userget, npcget);
                        distancemax += dtw_angle(npcget, maxqual2);
                        count = count + 1;
                        index = i;
                        break;
                    }
                }
            }

        }
        else if (npc_pose_seg.Count == user_pose_seg.Count)
        {
            for (int i = 0; i < npc_pose_seg.Count; i++)
            {
                ArrayList userget = TurntoArr_angle(user_pose_seg[i].angle);
                ArrayList npcget = TurntoArr_angle(npc_pose_seg[i].angle);
                ArrayList maxqual = TurntoArr_angle(maxzero);
                distancemax += dtw_angle(npcget, maxqual);
                distance += dtw_angle(userget, npcget);
                count = count + 1;
            }
        }
        else
        {
            int index = 1;
            float[] angle = new float[npc_pose_seg[0].numKey];

            foreach (var item in npc_pose_seg)
            {
                for (int i = index; i < user_pose_seg.Count; i++)
                {
                    if (user_pose_seg[i].coresp_time >= item.coresp_time)
                    {

                        double getfirst = Convert.ToDouble(GetTime(user_pose_seg[i - 1].coresp_time, item.coresp_time));
                        double getsecond = Convert.ToDouble(GetTime(item.coresp_time, user_pose_seg[i].coresp_time));

                        if (getfirst < 0)
                        {
                            getfirst = 0;
                        }
                        if (getsecond == 0)
                        {
                            for (int j = 0; j < user_pose_seg[i].numKey; j++)
                            {
                                angle[j] = user_pose_seg[i].angle[j];

                            }
                            ArrayList usergetequal = TurntoArr_angle(item.angle);
                            ArrayList npcgetequal = TurntoArr_angle(angle);
                            distance += dtw(usergetequal, npcgetequal);
                            ArrayList maxqual2 = TurntoArr_angle(maxzero);
                            distancemax += dtw_angle(npcgetequal, maxqual2);
                            count = count + 1;
                            index = i;
                            break;
                        }

                        for (int j = 0; j < user_pose_seg[i].numKey; j++)
                        {
                            angle[j] = Convert.ToSingle((getfirst / (getfirst + getsecond)) * (user_pose_seg[i - 1].angle[j])) + Convert.ToSingle((getsecond / (getfirst + getsecond)) * (user_pose_seg[i].angle[j]));


                        }
                        ArrayList userget = TurntoArr_angle(item.angle);
                        ArrayList npcget = TurntoArr_angle(angle);
                        ArrayList maxqual = TurntoArr_angle(maxzero);
                        distancemax += dtw_angle(npcget, maxqual);
                        distance += dtw_angle(userget, npcget);
                        count = count + 1;
                        index = i;
                        break;
                    }
                }
            }
        }
        double distancescore = 0;
        distance = distance / count;
        distancemax = distancemax / count;
        return distancemax;
        if (distance > Maxangledistance)
            return 0;
        else if (distance == Minangledistance)
            return 1;
        else
        {
           
            
            distancescore = 1 - (distance * distance*distance) / (distancemax * distancemax* distancemax);
        }
        return distancescore;

    }

    public static double score_pose(List<PoseKeyPoints> npc_pose_seg, List<PoseKeyPoints> user_pose_seg)
    {
        double distance = 0;
        int count = 0;
        int k = 0;
        if (npc_pose_seg.Count > user_pose_seg.Count)
        {
            int index = 1;
            float[] testposex = new float[npc_pose_seg[0].numKey];
            float[] testposey = new float[npc_pose_seg[0].numKey];
            foreach (var item in user_pose_seg)
            {
                for (int i = index; i < npc_pose_seg.Count; i++)
                {
                    if (npc_pose_seg[i].coresp_time >= item.coresp_time)
                    {
                        double getfirst = Convert.ToDouble(GetTime(npc_pose_seg[i - 1].coresp_time, item.coresp_time));
                        double getsecond = Convert.ToDouble(GetTime(item.coresp_time, npc_pose_seg[i].coresp_time));
                        if (getfirst < 0)
                        {
                            getfirst = 0;
                        }
                        if (getsecond == 0)
                        {
                            for (int j = 0; j < npc_pose_seg[i].numKey; j++)
                            {
                                testposex[j] = npc_pose_seg[i].pose_x[j];
                                testposey[j] = npc_pose_seg[i].pose_y[j];

                            }
                            ArrayList usergetequal = TurntoArr(item.pose_x, item.pose_y);
                            ArrayList npcgetequal = TurntoArr(testposex, testposey);
                            distance += dtw(usergetequal, npcgetequal);
                            count = count + 1;
                            index = i;
                            break;
                        }

                        for (int j = 0; j < npc_pose_seg[i].numKey; j++)
                        {
                            testposex[j] = Convert.ToSingle((getfirst / (getfirst + getsecond)) * (npc_pose_seg[i - 1].pose_x[j])) + Convert.ToSingle((getsecond / (getfirst + getsecond)) * (npc_pose_seg[i].pose_x[j]));
                            testposey[j] = Convert.ToSingle((getfirst / (getfirst + getsecond)) * (npc_pose_seg[i - 1].pose_y[j])) + Convert.ToSingle((getsecond / (getfirst + getsecond)) * (npc_pose_seg[i].pose_y[j]));

                        }
                        ArrayList userget = TurntoArr(item.pose_x, item.pose_y);
                        ArrayList npcget = TurntoArr(testposex, testposey);
                        distance += dtw(userget, npcget);
                        
                        
                        count = count + 1;
                        index = i;
                        break;
                    }
                }
            }

        }
        else if (npc_pose_seg.Count == user_pose_seg.Count)
        {
            for (int i = 0; i < npc_pose_seg.Count; i++)
            {
                ArrayList userget = TurntoArr(user_pose_seg[i].pose_x, user_pose_seg[i].pose_y);
                ArrayList npcget = TurntoArr(npc_pose_seg[i].pose_x, npc_pose_seg[i].pose_y);
                distance += dtw(userget, npcget);
                count = count + 1;
                
            }
        }
        else
        {
            int index = 1;
            float[] testposex = new float[npc_pose_seg[0].numKey];
            float[] testposey = new float[npc_pose_seg[0].numKey];
            foreach (var item in npc_pose_seg)
            {
                for (int i = index; i < user_pose_seg.Count; i++)
                {
                    if (user_pose_seg[i].coresp_time >= item.coresp_time)
                    {
                        double getfirst = Convert.ToDouble(GetTime(user_pose_seg[i - 1].coresp_time, item.coresp_time));
                        double getsecond = Convert.ToDouble(GetTime(item.coresp_time, user_pose_seg[i].coresp_time));
                        if (getfirst < 0)
                        {
                            getfirst = 0;
                        }
                        if (getsecond == 0)
                        {
                            for (int j = 0; j < user_pose_seg[i].numKey; j++)
                            {
                                testposex[j] = user_pose_seg[i].pose_x[j];
                                testposey[j] = user_pose_seg[i].pose_y[j];

                            }
                            ArrayList usergetequal = TurntoArr(item.pose_x, item.pose_y);
                            ArrayList npcgetequal = TurntoArr(testposex, testposey);
                            distance += dtw(usergetequal, npcgetequal);
                            count = count + 1;
                            index = i;
                            break;
                        }

                        for (int j = 0; j < user_pose_seg[i].numKey; j++)
                        {
                            testposex[j] = Convert.ToSingle((getfirst / (getfirst + getsecond)) * (user_pose_seg[i - 1].pose_x[j])) + Convert.ToSingle((getsecond / (getfirst + getsecond)) * (user_pose_seg[i].pose_x[j]));
                            testposey[j] = Convert.ToSingle((getfirst / (getfirst + getsecond)) * (user_pose_seg[i - 1].pose_y[j])) + Convert.ToSingle((getsecond / (getfirst + getsecond)) * (user_pose_seg[i].pose_y[j]));

                        }
                        ArrayList userget = TurntoArr(item.pose_x, item.pose_y);
                        ArrayList npcget = TurntoArr(testposex, testposey);
                        distance += dtw(userget, npcget);
                        count = count + 1;
                        index = i;
                        break;
                    }
                }
            }
        }
        double distancescore = 0;
        distance = distance / count;
        
        if (distance > Maxdistance)
            return 0;
        else if (distance < Mindistance)
            return 3;
        else
        {
            distancescore = (1 - (distance - Mindistance) / (Maxdistance - Mindistance));
        }
        return distance;
    }


    /// <summary>
    /// 计算两段序列的相似度
    /// </summary>
    /// <param name="npc_pose_seg">npc的骨骼帧</param>
    /// <param name="user_pose_seg">用户的骨骼帧</param>
    /// <returns></returns>
    private double score_calulator(List<PoseKeyPoints> npc_pose_seg, List<PoseKeyPoints> user_pose_seg)
    {
        double distance = 0;
        for (int i = 0; i < npc_pose_seg.Count; i++)
        {
            ArrayList userget = TurntoArr(user_pose_seg[i].pose_x, user_pose_seg[i].pose_y);
            ArrayList npcget = TurntoArr(npc_pose_seg[i].pose_x, npc_pose_seg[i].pose_y);
            distance += dtw(userget, npcget);
        }
        return distance;
    }

    /// <summary>
    /// 根据两段骨骼序列转角的L1距离得到得分. 要求两个序列的帧数一致且每帧对应时间一致
    /// </summary>
    /// <param name="pose_a"></param>
    /// <param name="pose_b"></param>
    /// <returns></returns>
    public static float L1_score_calulator(List<PoseKeyPoints> pose_a, List<PoseKeyPoints> pose_b)
    {
        if (pose_a.Count > pose_b.Count)
        {
            pose_a = PoseTimeSeries.Fit_forward(pose_b, pose_a);
        }
        else if (pose_a.Count < pose_b.Count)
        {
            pose_b = PoseTimeSeries.Fit_forward(pose_b, pose_a);
        }
        float off_set = 0.0f;
        // 与零向量的距离
        float zero_off_set = 0.0f;
        float[] zero_keypoints = new float[pose_a[0].numKey];
        for (int i = 0; i < zero_keypoints.Length; i++)
        {
            zero_keypoints[i] = 0;
        }

        for (int i = 0; i < pose_a.Count; i++)
        {

            off_set += list_distance(pose_a[i].angle, pose_b[i].angle);
            zero_off_set += list_distance(pose_a[i].angle, zero_keypoints);
        }
        return (zero_off_set - off_set) / zero_off_set;
        //return off_set;
    }

    private IEnumerator calculating()
    {
        // 当完成的动作小于npc的动作个数时 协程运行
        int current = finish + 1;
        List<PoseKeyPoints> npc_pose_seg = npc.getMotion(current);
        var finish_time = npc_pose_seg[npc_pose_seg.Count - 1].coresp_time;
        while (finish < npc.num_motion)
        {
            if (current == finish)
            {
                // 更新npc动作
                current++;
                npc_pose_seg = npc.getMotion(current);
                finish_time = npc_pose_seg[npc_pose_seg.Count - 1].coresp_time;
            }
            if (DateTime.Now >= finish_time)
            {
                List<PoseKeyPoints> user_pose_seg = openPose.GetPoseSeg(npc_pose_seg[0].coresp_time, finish_time);
                //npc_pose_seg = PoseTimeSeries.Fit_forward(user_pose_seg, npc_pose_seg);
                scores.Add((float)score_angle(npc_pose_seg, user_pose_seg));
                finish++;
            }
            yield return new WaitForSeconds(0.01f);
        }
        gameObject.SetActive(false);

    }

}